/*
 * Created on 2005/04/29
 * Author aki@www.xucker.jpn.org
 * License Apache2.0 or Common Public License
 */
package jp.sourceforge.akjrcp.snack;

import jp.sourceforge.akjrcp.audiotools.WaveFormViewer;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.Graphics;
import org.eclipse.draw2d.geometry.Point;
import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.swt.graphics.Color;



/**
 * 
 *
 */
public class FormantFigure extends Figure{
    public static Log log = LogFactory.getLog(FormantFigure.class);

private double formantFrameMilliSecond=10;//0.01 second default formant.exe executed value.

private final double basePPS=6.25;//pixel per millisecond.	//this is tuned as pps
SmallFormant[] formants;
private int drawHeight=512;
private double offsetX;	//some case you have to set because spectrom ignore first height samples. 
//private int maxHeltz=5501;//fit mode?

private int sampleRate=48000;

private double wzoom=1;
private double viewpps=basePPS*wzoom;//pixel per millisecond.

private boolean syncParent=true;//for scroll
public double getWzoom() {
    return wzoom;
}
public void setWzoom(double wzoom) {
    this.wzoom = wzoom;
    viewpps=basePPS/wzoom;//
    resize();
}
public boolean isFit() {
    return fit;
}
public void setFit(boolean fit) {
    this.fit = fit;
}
public int getSampleRate() {
    return sampleRate;
}
public void setSampleRate(int sampleRate) {
	
    this.sampleRate = sampleRate;
}
private boolean fit;
private boolean drawUnder=true;
public void resize(){
    if(formants!=null){
    setSize((int)(formants.length*(formantFrameMilliSecond/viewpps)),drawHeight);
    log.trace("resize():"+getSize());
    }
    }

private int marginY;
public int getMarginX() {
    return marginX;
}
public void setMarginX(int marginX) {
    this.marginX = marginX;
}
public int getMarginY() {
    return marginY;
}
public void setMarginY(int marginY) {
    this.marginY = marginY;
}
private int marginX;

private int toYLocation(double value){

    if(fit){
       // log.infofit:"+sampleRate);
        //max helz is half of sampleRate.
        return drawHeight-(int)((drawHeight-(marginY*2))*(value/(sampleRate/2)));
        }else{
        	if(drawUnder){
        		 
        		 return getParent().getClientArea().height-(int)((drawHeight-(marginY*2))*(value/(sampleRate/2)));//TODO check client area	
        	}else{
            return drawHeight-(int)((drawHeight-(marginY*2))*(value/(sampleRate/2)));
        	}
            
    }
}


private Color[] fColor={new Color(null,255,0,0),new Color(null,0,255,0),new Color(null,0,0,255)};

public void paintFigure(Graphics g) {
	//log.info(WaveFormViewer.self.waveInfoCanvas.getBounds());
	org.eclipse.swt.graphics.Rectangle r=WaveFormViewer.self.waveInfoCanvas.getBounds();
	Rectangle clip=new Rectangle(r.x,r.y,r.width,r.height);
	g.clipRect(clip);
	//log.trace("parent:"+getParent().getClientArea());
	//log.trace("x:"+getParent().getBounds().x);
   // log.trace("paintFigure:"+this.getClientArea());
    //TODO now draw F1 F2 F3
    //add F4 and draw by setting.
    
    //TODO future support.
    double ignorePixel=0;//drawHeight*(1000/basePPS*wzoom)/sampleRate;//spectrogram read something 512 pixel
    
    int offset=(int) (offsetX*wzoom);
    if(syncParent){
    	offset+=getParent().getBounds().x;
    }
    
    Point preF[]=new Point[3];
    if(formants!=null ){
        log.trace("formantsize:"+formants.length);
   // log.trace("formant-length:"+formants.length);
    
        double resize=formantFrameMilliSecond/viewpps;
        log.trace("resize:"+resize);
        for(int i=0;i<formants.length;i++){
        
        for(int j=0;j<3;j++){
        //log.info"+f1);
        double f;
        if(j==0){
            f=formants[i].getF1();
        }else if(j==1){
            f=formants[i].getF2();
        }else{
            f=formants[i].getF3();
        }
        
        Point currentF=new Point((double)offset+(double)ignorePixel+(double)marginX*wzoom+((double)i*resize),marginY+toYLocation(f));
       // if(j==2 &&i>5800)
       // log.info(i+",y="+toYLocation(f)+","+offset+","+ignorePixel+","+marginX+","+resize+","+(int)(i*resize));
        g.setForegroundColor(fColor[j]);
        //g.setBackgroundColor(fColor[j]);
        
        if(i==100 && j==0){
       // log.trace(""+i+","+marginX+","+preF[j]+","+currentF);
        }
        
        if(preF[j]!=null){
        if(clip.contains(preF[j]) && clip.contains(currentF)){
        	g.drawLine(preF[j],currentF);
        	}
        
        }else{
        g.drawLine(currentF,currentF);
        }
        preF[j]=currentF;
        }
        /*
        
        int f2=toCordinate(formants[i].getF2());
        drawY=dy-myy-f2;
        gb.setForeground(f2Color);
        if(x2>myx){
        gb.drawLine(x1,preF2,x2,drawY);
        }
        preF2=drawY;
        
        int f3=toCordinate(formants[i].getF3());
        drawY=dy-myy-f3;
        gb.setForeground(f3Color);
        if(x2>myx){
        gb.drawLine(x1,preF3,x2,drawY);
        }
        preF3=drawY;
        */
    }
    }
}

/**
 * @param formants2
 */
public void setFormants(SmallFormant[] formants) {
    this.formants=formants;
    resize();
    //setSize(formants.length*4,512);//TODO change better.
}
public double getOffsetX() {
	return offsetX;
}
public void setOffsetX(double offsetX) {
	this.offsetX = offsetX;
}
}
